﻿// Copyright (C) 2008,2009,2010 by Tom Kao & MISOO Team & Yonghua Jin. All rights reserved.
// Released under the terms of the GNU Library or Lesser General Public License (LGPL).
// Author: Tom Kao(中文名：高焕堂)，MISOO团队，Yonghua Jin(中文名：金永华)
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are
// met:
//    * Redistributions of source code must retain the above copyright
//	notice, this list of conditions and the following disclaimer.
//    * Redistributions in binary form must reproduce the above
//	copyright notice, this list of conditions and the following disclaimer
//	in the documentation and/or other materials provided with the
//	distribution.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.

#ifndef LW_OOPC_H_INCLUDED_
#define LW_OOPC_H_INCLUDED_

#include "ooc_typedef.h"
#include "mem_leak.h"


//---------------配置---------------------------------------------------------------
#define OOC_SWITCH_ON                   1
#define OOC_SWITCH_OFF                  0

#define OOC_CFG_SW_DEBUG            OOC_SWITCH_ON





//---------------内存管理与检测-----------------------------------------------------------------------
#if (OOC_CFG_SW_DEBUG == OOC_SWITCH_ON)


#define OOC_MALLOC(size)    ObjectClass.tDbg.tMLeak.malloc(size, __FILE__, __LINE__)
#define OOC_FREE(obj)       ObjectClass.tDbg.tMLeak.free(cthis, obj)

#else


#define OOC_MALLOC(size)    malloc(size)
#define OOC_FREE(obj)       free(obj)

#endif

//------------编程工具---------------------------------------------------------
//根据结构体的元素地址以及结构体的定义来计算结构体的首地址并将其转化成结构体指针。(ea:Element Address  sn: struct name en:element name)
#define OOC_SHIFT_TO_STRUCT_HEAD_ADDR(ea, sn, en)   ((sn*)((size_t)ea - (size_t)&(((sn*)0)->en)))

//-----------包名空间定义工具---------------------------------------------------------------------------
//包名称定义(Package Name)
#define _OOC_PKG_PNAME(upper, pkg)              upper##pkg
#define OOC_PKG_PNAME(upper, pkg)               _OOC_PKG_PNAME(upper, pkg)


//包中元素的名称定义(Package Element Name)
#define _OOC_PKG_ENAME(pkg, type)               pkg##type
#define OOC_PEN(pkg, type)                      _OOC_PKG_ENAME(pkg, type)


//默认包定义(Default Package)
#define OOC_DPKG                                OOC_PKG_PNAME(,)

//测试包定义
#define OOC_TEST_PKG                            OOC_PKG_PNAME(,Test_)


//------------------函数名定义工具--------------------------------------------------------------
//对名称进行重载(Override)
#define _OOC_ONAME(name, suffix)                name##_suffix
#define OOC_ONAME(name, suffix)                 _OOC_ONAME(name, suffix)

//构造函数的名称定义
#define _OOC_CTOR_NAME(type)                    new_##type 
#define OOC_CTOR_NAME(type)                     _OOC_CTOR_NAME(type)
#define OOC_CTOR_NAME_P(pkg, type)              OOC_CTOR_NAME(OOC_PEN(pkg, type))
//-------------------数据结构类型定义工具-----------------------------------------------------------------------
//类结构体类型定义工具
#define _OOC_STRUCT_DEF_(type)                  \
typedef struct type type;                       \
struct type


//接口的类型定义
#define OOC_INTERFACE_DEF_(pkg, type)           _OOC_STRUCT_DEF_(OOC_PEN(pkg, type))

//普通类的类型定义(类的公共结构体)
#define OOC_CLASS_TNAME(type)                   type
#define OOC_CLASS_TNAME_P(pkg, type)            OOC_PEN(pkg, type)
#define OOC_CLASS_DEF_(pkg, type)               _OOC_STRUCT_DEF_(OOC_CLASS_TNAME_P(pkg, type))


//...............................................................................
//类的静态结构体的类型定义
#define _OOC_CLASS_STA_TNAME(type)              Sta##type
#define OOC_CLASS_STA_TNAME(type)               _OOC_CLASS_STA_TNAME(type)
#define OOC_CLASS_STA_TNAME_P(pkg, type)        OOC_PEN(pkg, OOC_CLASS_STA_TNAME(type))
#define OOC_CLASS_STA_DEF_(pkg, type)           _OOC_STRUCT_DEF_(OOC_CLASS_STA_TNAME_P(pkg, type))

//类的静态结构体的变量定义
#define _OOC_CLASS_STA_VNAME(type)              type##Class
#define OOC_CLASS_STA_VNAME(type)               _OOC_CLASS_STA_VNAME(type)
#define OOC_CLASS_STA_VNAME_P(pkg, type)        OOC_CLASS_STA_VNAME(OOC_PEN(pkg, type))
#define OOC_CLASS_STA_DEF(pkg, type)            OOC_CLASS_STA_TNAME_P(pkg, type) OOC_CLASS_STA_VNAME_P(pkg, type)


//类的静态结构体的初始化函数定义
#define _OOC_CLASS_INIT_FUNC_NAME(type)         type##_Class_Init
#define OOC_CLASS_INIT_FUNC_NAME(type)          _OOC_CLASS_INIT_FUNC_NAME(type)
#define OOC_CLASS_INIT_FUNC_NAME_P(pkg, type)   OOC_CLASS_INIT_FUNC_NAME(OOC_PEN(pkg, type))
#define OOC_CLASS_INIT_FUNC_DEF(pkg, type)      void OOC_CLASS_INIT_FUNC_NAME_P(pkg, type)(void)
//..........................................................................................
//类的保护结构体的类型定义
#define _OOC_CLASS_PRO_TNAME(type)              Pro##type
#define OOC_CLASS_PRO_TNAME(type)               _OOC_CLASS_PRO_TNAME(type)
#define OOC_CLASS_PRO_TNAME_P(pkg, type)        OOC_CLASS_PRO_TNAME(OOC_PEN(pkg, type))
#define OOC_CLASS_PRO_DEF_(pkg, type)           _OOC_STRUCT_DEF_(OOC_CLASS_PRO_TNAME_P(pkg, type))

//类的私有结构体的类型定义
#define _OOC_CLASS_PRI_TNAME(type)              Pri##type
#define OOC_CLASS_PRI_TNAME(type)               _OOC_CLASS_PRI_TNAME(type)
#define OOC_CLASS_PRI_TNAME_P(pkg, type)        _OOC_CLASS_PRI_TNAME(OOC_PEN(type))
#define OOC_CLASS_PRI_DEF_(pkg, type)           _OOC_STRUCT_DEF_(OOC_CLASS_PRI_TNAME_P(type))
//.....................................................................................
//类的公共块结构体的类型定义
#define _OOC_PUB_BLOCK_TNAME(type)              Pub##type##Block
#define OOC_PUB_BLOCK_TNAME(type)               _OOC_PUB_BLOCK_TNAME(type)
#define OOC_PUB_BLOCK_TNAME_P(pkg, type)        OOC_PUB_BLOCK_TNAME(OOC_PEN(pkg, type))

#define OOC_PUB_BLOCK_DEF(pkg, type)          \
        typedef struct{                         \
            /*tLink字段必需位于type字段的前面，且必需相邻*/ \
            OOC_ClassLinkDef            tLink;              \
            struct OOC_PEN(pkg, type)   type;               \
        }OOC_PUB_BLOCK_TNAME_P(pkg, type)


#define OOC_GET_PUB_BLOCK(cthis, pkg, type)     OOC_SHIFT_TO_STRUCT_HEAD_ADDR(cthis, OOC_PUB_BLOCK_TNAME_P(pkg, type), type)
#define OOC_GET_LINK_BY_CTHIS(cthis)            ((OOC_ClassLinkDef*)cthis - 1)

//-----------面向对象的语意定义-----------------------------------------------------------------------
//接口实现的语义定义
#define OOC_IMPLEMENTS(pkg, type)               struct OOC_PEN(pkg, type)           type

//类继承的语义定义(公共部分)
#define OOC_EXTENDS(pkg, type)                  struct OOC_PEN(pkg, type)*          type


//类继承的语义定义(保护部分)
#define OOC_PRO_EXTENDS(pkg, type)              OOC_CLASS_PRO_TNAME_P(pkg, type)*   type

//类继承的语义定义(私有部分)
#define OOC_PRI_EXTENDS(pkg, type)              OOC_CLASS_PRI_TNAME_P(type)*        type

//虚函数的注释性标记宏定义
#define OOC_abstract    /*void*/

//函数覆盖的注释性标记宏定义(覆盖父类中的方法)
#define OOC_override    /*void*/

//函数重载的注释性标记宏定义(在同一类中定义具有相同语意但不同函数筌名的多个方法)
#define OOC_overload    /*void*/
//------------对象定义----------------------------------------------------------
//类的元数据结构体定义
#define _OOC_CLASS_META_VNAME(type)             t##type##Meta
#define _OOC_TYPE_NAME_STRING(type)             #type
#define OOC_CLASS_META_VNAME(type)              _OOC_CLASS_META_VNAME(type)
#define OOC_CLASS_META_VNAME_P(pkg, type)       OOC_CLASS_META_VNAME(OOC_PEN(pkg, type))



#define OOC_CLASS_META(type_pkg, type, super_pkg, super_type)                                         \
    extern OOC_ClassMetaDef OOC_CLASS_META_VNAME_P(super_pkg, super_type);                              \
    struct OOC_ClassMeta OOC_CLASS_META_VNAME_P(type_pkg, type) = {                                     \
                                                        _OOC_TYPE_NAME_STRING(type),                   \
                                                        &OOC_CLASS_META_VNAME_P(super_pkg, super_type)  \
                                                      }

typedef struct OOC_ClassMeta {
    mu8* sName; //类名称
    struct OOC_ClassMeta* pSuper; //超类信息定义
} OOC_ClassMetaDef; //类的元数据结构体定义

typedef struct {
    struct OOC_ClassCore* pCore; //类核心

    void* pPublic; //类的公有部分
    void* pProtected; //类的保护部分
    void* pPrivate; //类的私有部分    
} OOC_ClassLinkDef; //类的内部对象的连结关系定义

typedef struct OOC_ClassCore {
    OOC_ClassMetaDef* pMetaData; //类信息
    void* cthis; //顶层类的公有结构体指针

    struct {
        void (*finalize)(void* cthis);//顶层类对象的析构函数

        struct {
            mbool bReleased : 1; //用户释放标志
            mu8 nRefCNT : 7; //类内部引用计数器
        } tFlags; //标志
    } tCtrlBlk; //控制块
    
#if (OOC_CFG_SW_DEBUG == OOC_SWITCH_ON)
    struct{
        CListDef*   pDbgNode;   //用于调试的信息块链表结点
    }tDebug;
#endif    
    
} OOC_ClassCoreDef; //类核心结构体定义




#if (OOC_CFG_SW_DEBUG == OOC_SWITCH_ON)
    typedef struct{
        OOC_ClassCoreDef* pObjCore;
        struct{
            MLeakDef tDetector;
        }tMLeak;
    }OOC_ClassDbgBlkDef;

#endif



#endif